!!M Inlines.f
C  The compiler directive above gives us access
C  to the Macintosh Toolbox.
C-------------------------------------------------
C  This program determines the time needed to
C  perform matrix multiplcation, and also finds
C  out how the total time is divided between
C  actual floating-point calculations and index-
C  ing overhead.
C
C  April 1990.
C  Jon Bell, Dept. of Physics & Computer Science
C  Presbyterian College, Clinton SC.
C
C  Written in Language Systems FORTRAN, v2.0.
C-------------------------------------------------
      IMPLICIT NONE
      INTEGER I, J
      EXTENDED TOTAL, OVERHEAD, CALCS
      EXTENDED A(3,5), B(5,3), C(3,3)
      DATA ((A(I,J), J=1,5), I=1,3)
     &     /  -2.0, -7.0, -4.0,  8.0,  1.0,
     &        -3.0,  0.0, -1.0,  0.0, -9.0,
     &         0.0, -1.0, -8.0, -9.0, -3.0  /
      DATA ((B(I,J), J=1,3), I=1,5)
     &     /  -1.0,  3.0, -2.0,
     &         4.0, -1.0,  1.0,
     &         9.0, -4.0, -8.0,
     &        -5.0,  0.0, -3.0,
     &         6.0,  3.0, -6.0  /
C
C  First demonstrate that the matrix 
C  multiplication works properly.
C
      CALL MXMPY (A, B, C, 3, 5, 3)
      TYPE *, 'Matrix A is:'
      TYPE *
      CALL MATPRINT (A, 3, 5)
      TYPE *
      TYPE *, 'Matrix B is:'
      TYPE *
      CALL MATPRINT (B, 5, 3)
      TYPE *
      TYPE *, 'Their product is:'
      TYPE *
      CALL MATPRINT (C, 3, 3)
      TYPE *
C
C  Find the time it takes to multiply matrices
C  of various sizes.
C
      TYPE *
      TYPE *, 'Time to multiply two matrices:'
      TYPE *
      TYPE *, '      Size           Total',
     *        '      Overhead          Calcs'
      TYPE *, '----------     -----------',
     *        '    ----------     ----------'
      CALL TIMER (5, TOTAL, OVERHEAD, CALCS)
      TYPE 100, '5 x 5', TOTAL, OVERHEAD, CALCS
      CALL TIMER (10, TOTAL, OVERHEAD, CALCS)
      TYPE 100, '10 x 10', TOTAL, OVERHEAD, CALCS
      CALL TIMER (20, TOTAL, OVERHEAD, CALCS)
      TYPE 100, '20 x 20', TOTAL, OVERHEAD, CALCS
      CALL TIMER (50, TOTAL, OVERHEAD, CALCS)
      TYPE 100, '50 x 50', TOTAL, OVERHEAD, CALCS
100   FORMAT (1X, A10, 3(5X, F10.3))
      END

      SUBROUTINE MATINIT (A, M, N)
C-------------------------------------------------
C  Initialize the array A as a M x N matrix.
C-------------------------------------------------
      IMPLICIT NONE
      INTEGER M, N, I, J
      EXTENDED A(M,N)
      DO I = 1, M
         DO J = 1, N
            A(I,J) = REAL(I+J)
         END DO
      END DO
      END

      SUBROUTINE MATPRINT (A, M, N)
C-------------------------------------------------
C  Prints the contents of the M x N matrix A.
C  Both dimensions must not be greater than 10.
C-------------------------------------------------
      IMPLICIT NONE
      INTEGER M, N, I, J
      EXTENDED A(M,N)
      DO I = 1, M
          TYPE '(10F8.1)', (A(I,J), J=1,N)
      END DO
      END

      SUBROUTINE TIMER 
     *   (SIZE, TOTAL, OVERHEAD, CALCS)
C-------------------------------------------------
C  Determine the time required to multiply two
C  SIZE x SIZE matrices (where SIZE <= 50).
C     TOTAL = total time (seconds). 
C     OVERHEAD = indexing overhead (seconds).
C     CALCS = actual time spent in float-
C  ing-point calculations (seconds).
C-------------------------------------------------
      IMPLICIT NONE
      INTEGER SIZE, TICKS, STARTTICKS, 
     *        STOPTICKS, J
      EXTENDED TOTAL, OVERHEAD, CALCS
      EXTENDED SOURCE(50,50), RESULT(50,50)
      CALL MATINIT (SOURCE, SIZE, SIZE)
C
C  Multiply the matrix by itself ten times and 
C  find the average time per multiplication.
C  Notice that we're using only part of the 
C  matrix.  Although it's declared here as 50x50,
C  all the other subroutines will think it's
C  really SIZE x SIZE!
C
      TICKS = 0
      DO J = 1, 10
         STARTTICKS = TICKCOUNT()
         CALL MXMPY (SOURCE, SOURCE, RESULT, SIZE,
     *               SIZE, SIZE)
         STOPTICKS = TICKCOUNT()
         TICKS = TICKS + (STOPTICKS - STARTTICKS)
      END DO
      TOTAL = REAL(TICKS) / 600.0
C
C  Repeat with a ÒdummyÓ routine which has all the 
C  indexing overhead of the matrix multiplication
C  but doesnÕt actually do any arithmetic.
C
      TICKS = 0
      DO J = 1, 10
         STARTTICKS = TICKCOUNT()
         CALL DUMMY (SOURCE, SOURCE, RESULT,
     *                 SIZE, SIZE, SIZE)
         STOPTICKS = TICKCOUNT()
         TICKS = TICKS + (STOPTICKS - STARTTICKS)
      END DO
      OVERHEAD = REAL(TICKS) / 600.0
C
C  Calculate the average time spent doing actual
C  arithmetic.
C
      CALCS = TOTAL - OVERHEAD
      END
